package com.hl.lib.utils

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.doublePreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.floatPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map

@SuppressLint("StaticFieldLeak")
object DataStorePreferences {

    private lateinit var mContext: Context

    fun init(context: Context) {
        mContext = context.applicationContext
    }

    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "appDataStore")


    suspend fun putString(key: String, value: String) {
        mContext.dataStore.edit { preferences ->
            preferences[stringPreferencesKey(key)] = value
        }
    }

    suspend fun getString(key: String, defaultValue: String = ""): String {
        return mContext.dataStore.data.map { preferences ->
            preferences[stringPreferencesKey(key)] ?: defaultValue
        }.first()
    }

    suspend fun putInt(key: String, value: Int) {
        mContext.dataStore.edit { preferences ->
            preferences[intPreferencesKey(key)] = value
        }
    }

    suspend fun getInt(key: String, defaultValue: Int = 0): Int {
        return mContext.dataStore.data.map { preferences ->
            preferences[intPreferencesKey(key)] ?: defaultValue
        }.first()
    }

    suspend fun putLong(key: String, value: Long) {
        mContext.dataStore.edit { preferences ->
            preferences[longPreferencesKey(key)] = value
        }
    }

    suspend fun getLong(key: String, defaultValue: Long = 0L): Long {
        return mContext.dataStore.data.map { preferences ->
            preferences[longPreferencesKey(key)] ?: defaultValue
        }.first()
    }


    suspend fun putFloat(key: String, value: Float) {
        mContext.dataStore.edit { preferences ->
            preferences[floatPreferencesKey(key)] = value
        }
    }

    suspend fun getFloat(key: String, defaultValue: Float = 0.0f): Float {
        return mContext.dataStore.data.map { preferences ->
            preferences[floatPreferencesKey(key)] ?: defaultValue
        }.first()
    }



    suspend fun putDouble(key: String, value: Double) {
        mContext.dataStore.edit { preferences ->
            preferences[doublePreferencesKey(key)] = value
        }
    }

    suspend fun getDouble(key: String, defaultValue: Double = 0.0): Double {
        return mContext.dataStore.data.map { preferences ->
            preferences[doublePreferencesKey(key)] ?: defaultValue
        }.first()
    }

    suspend fun putBoolean(key: String, value: Boolean) {
        mContext.dataStore.edit { preferences ->
            preferences[booleanPreferencesKey(key)] = value
        }
    }

    suspend fun getBoolean(key: String, defaultValue: Boolean = false): Boolean {
        return mContext.dataStore.data.map { preferences ->
            preferences[booleanPreferencesKey(key)] ?: defaultValue
        }.first()
    }

    fun getStringFlow(key: String, defaultValue: String = ""): Flow<String> {
        return mContext.dataStore.data.map { preferences ->
            preferences[stringPreferencesKey(key)] ?: defaultValue
        }
    }

    fun getIntFlow(key: String, defaultValue: Int = 0): Flow<Int> {
        return mContext.dataStore.data.map { preferences ->
            preferences[intPreferencesKey(key)] ?: defaultValue
        }
    }

    fun getLongFlow(key: String, defaultValue: Long = 0): Flow<Long> {
        return mContext.dataStore.data.map { preferences ->
            preferences[longPreferencesKey(key)] ?: defaultValue
        }
    }

    fun getLongFlow(key: String, defaultValue: Float = 0.0f): Flow<Float> {
        return mContext.dataStore.data.map { preferences ->
            preferences[floatPreferencesKey(key)] ?: defaultValue
        }
    }

    fun getLongFlow(key: String, defaultValue: Double = 0.0): Flow<Double> {
        return mContext.dataStore.data.map { preferences ->
            preferences[doublePreferencesKey(key)] ?: defaultValue
        }
    }

    fun getBooleanFlow(key: String, defaultValue: Boolean = false): Flow<Boolean> {
        return mContext.dataStore.data.map { preferences ->
            preferences[booleanPreferencesKey(key)] ?: defaultValue
        }
    }
}
